from BaseController import BaseController
from Utility import ParameterKey
from Utility import ViewName
from Utility import FormData
from Utility import SessionKey
from Utility import TemplateValueName
from Utility import IsEmptyString
from Biz.LogIn import LogIn
from Biz.LogIn import GetProfileInfo
from gaesessions import get_current_session
import Configuration
from Common.Validator import Validator
from urllib import quote
import base64


class LogInController(BaseController):
    def get(self):
        """
        Render Login page and return user.
            It will try to get Organization name by query string("org=")
            It will try to get which page the user is redirected from by query string("re=")
            These two data are stored in hidden input controls.
        """
                
        redirectURL = self.request.get(ParameterKey.REDIRECT_URL)
        if IsEmptyString(redirectURL):
            redirectURL = Configuration.DEFAULT_LOGIN_REDIRECT
            
        #
        # Check if user has logged in
        #
#        session = get_current_session()
        u = self.GetCurrentUser()
        # if user has logged in
        if u is not None:
            # redirect to previous link or to default link
            self.redirect(redirectURL)
            return
        
        #
        # get user info from cookie
        #
        
        c_key = self.request.cookies.get('authn', '')
        
        
        if not IsEmptyString(c_key):
            e_key=base64.b16decode(base64.b16decode(base64.b16decode(c_key)))
            
            #
            # Log in logic
            #
            newu = GetProfileInfo(e_key)
            
            if (newu is not None):
                session = get_current_session()
                session[SessionKey.CURRENT_USER] = newu
                session.regenerate_id()
                return self.redirect(redirectURL) 
            else:
                self.response.headers.add_header('Set-Cookie', 'authn=%s; expires=Fri, 31-Dec-2000 23:59:59 GMT' % (""))           
        
        #
        # render login UI  
        #
        orgName = self.request.get(ParameterKey.COMPANY_NAME)
        #if IsEmptyString(orgName):
        #    orgName = Configuration.DEFAULT_COMPANY_NAME
        
        template_values = {TemplateValueName.ORG_NAME: orgName, 
                           TemplateValueName.REDIRECT_URL: redirectURL}
        self.Render(ViewName.LOGIN, template_values)
        
        
    
    def post(self):
        """
        Do the actual login logic
            It will try to get UserName, Password, OrgName, IsStaySignedIn and RedirectURL from form data.
        """
        #
        # get user inputs
        #
        userName = self.request.get(FormData.USER_NAME)     
        passWord = self.request.get(FormData.PASSWORD)
        companyName = self.request.get('OrgName')
        redirectURL = self.request.get(FormData.REDIRECT_URL)
        
        #
        # Check if user inputs is empty
        #
        if IsEmptyString(userName) or IsEmptyString(passWord): #or IsEmptyString(companyName):
            template_values = {TemplateValueName.ERROR_MESSAGE: "UserName or Password cannot be empty!"}
            self.Render(ViewName.LOGIN, template_values)
            return 
        
        #
        # Check if user name and password are valid.
        #
        
        try: 
            Validator.name("username", userName)
        except:
            template_values = {TemplateValueName.ERROR_MESSAGE: "Please enter valid user name, it could not contain special characters"}
            self.Render(ViewName.LOGIN, template_values)
            return
        
#        try: 
#            Validator.password("passWord", passWord)
#        except:
#            template_values = {TemplateValueName.ERROR_MESSAGE: "Please enter valid password, it should require at least one upper case one digit and one special character"}
#            self.Render(ViewName.LOGIN, template_values)
#            return
        
        if IsEmptyString(redirectURL):
            redirectURL = Configuration.DEFAULT_LOGIN_REDIRECT
        
        #
        # Log in logic
        #
        u = LogIn(userName, passWord, companyName)
        
        if (u is None):
            # return LogIn
            template_values = {TemplateValueName.ORG_NAME: companyName, 
                           TemplateValueName.REDIRECT_URL: redirectURL,
                           TemplateValueName.ERROR_MESSAGE: "The UserName and Password do not match!"}
            self.Render(ViewName.LOGIN, template_values)
            return
        else:
            # check "if stay log in"
            # genereate cookie 
            session = get_current_session()
            session[SessionKey.CURRENT_USER] = u
            
            session.regenerate_id()
            
            #
            # Save Encrypt user name and password into cookie.
            # We will encrypt user name and password three times then store it into cookie.
            #
            
            e_key=base64.b16encode(base64.b16encode(base64.b16encode(str(u.key()))))
            
            self.response.headers.add_header('Set-Cookie', 'authn=%s; expires=Fri, 31-Dec-2020 23:59:59 GMT' % (quote(e_key))) 
           
            self.redirect(redirectURL)
        

"""
Google suggests that request and response objects follow the WebOb interfaces. This works for getting cookies from request:
username = self.request.cookies.get('username', '')
Unfortunately you can't use WebOb method response.set_cookie. But you can set cookies by hand:
self.response.headers.add_header(
        'Set-Cookie', 
        'username=%s; expires=Fri, 31-Dec-2020 23:59:59 GMT' \
          % username.encode())
You can find some other hints on google-app-engine discussions. I don't know if cookies work from django-helper.
"""